#include "session.h"

namespace myrpc
{
	namespace mynet
	{
		void Session::Start()
		{

			handle_->on<uvw::ErrorEvent>([=](const uvw::ErrorEvent & error, uvw::TcpHandle & handle) {
				std::cout << "error " << std::endl;
			});

			handle_->on<uvw::CloseEvent>([=](const uvw::CloseEvent &, uvw::TcpHandle &)
			{
				std::cout << "close" << std::endl;
			});

			handle_->on<uvw::DataEvent>([=](const uvw::DataEvent &event, uvw::TcpHandle & handle)
			{
				const char *start = nullptr;
				const char *per = nullptr;
				start = event.data.get();
				int bodylenght = event.length;
				per = start;
				do
				{
					if (bodylenght == 0)
					{
						break;
					}

					if (bodylenght_ == 0)
					{
						myrpc::Header header;
						header.ParseFromArray(per, 5);
						bodylenght_ = header.len();
						per = per + 5;
						bodylenght = bodylenght - 5;
						if (bodylenght == 0)
						{
							break;
						}
						if (bodylenght_ <= bodylenght)
						{
							myrpc::Request request;
							request.ParseFromArray(per, bodylenght_);
							bodylenght = bodylenght - bodylenght_;
							per = per + bodylenght_;
							PackagePtr pack(new Package);
							pack->body = request;
							pack->tcphandlePtr = this->shared_from_this();
							bodylenght_ = 0;
							this->packgereachhandle_(pack);
						}
						else
						{
							in_ = std::string(per);
							bodylenght_ = bodylenght_ - bodylenght;
						}
					}
					else
					{
						if (bodylenght_ <= bodylenght)
						{
							myrpc::Request request;
							char* buf = new char[bodylenght_ + 1];
							memset(buf, '\0', bodylenght_ + 1);
							memcpy(buf, per, bodylenght_);
							std::string appends(buf);
							in_.append(buf);
							bool b = request.ParseFromString(in_);
							request.id();
							bodylenght = bodylenght - bodylenght_;
							per = per + bodylenght_;
							PackagePtr pack(new Package);
							pack->body = request;
							pack->tcphandlePtr = this->shared_from_this();
							bodylenght_ = 0;
							this->packgereachhandle_(pack);
							if (bodylenght == 0)
							{
								break;
							}
						}
						else
						{
							in_ = std::string(per);
							bodylenght_ = bodylenght_ - bodylenght;
						}
					}
				} while (true);
			});

			handle_->on<uvw::EndEvent>([=](const uvw::EndEvent &, uvw::TcpHandle &handle)
			{
				std::cout << "end" << std::endl;
				int count = 0;
				handle.loop().walk([&count](uvw::BaseHandle &) { ++count; });
				std::cout << "still alive: " << count << " handles" << std::endl;
			});


			handle_->on<uvw::WriteEvent>([=](const uvw::WriteEvent & event, uvw::TcpHandle &handle)
			{
				std::cout << "write" << std::endl;
			});

			handle_->read();

		}

		int Session::Send(std::string data, int len)
		{
			handle_->write(const_cast<char*>(data.c_str()), len);
			return 0;
		}

	}
}


